#!/usr/bin/env python
# -*- coding:utf-8 -*-

# file:do_exam1.py
# author:王雯雯
# datetime:2024-12-7
# software: PyCharm

import socket
import threading

# 创建TCP套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 绑定本地地址和端口
server_address = ('localhost', 6666)
server_socket.bind(server_address)

# 监听端口，允许最多10个连接同时等待
server_socket.listen(10)
print('多人聊天室服务器正在启动，监听端口 6666...')

# 存储所有客户端连接的套接字和对应的昵称
clients = []
nicknames = []


# 向所有客户端发送消息的函数
def broadcast(message, client_socket):
    for client in clients:
        if client!= client_socket:
            try:
                client.send(message)
            except:
                continue


# 处理客户端连接的线程函数
def handle_client(client_socket):
    while True:
        try:
            # 接收客户端发送的数据，每次最多接收1024字节
            data = client_socket.recv(1024)
            if data:
                message = data.decode('utf-8')
                print(message)
                broadcast(message.encode('utf-8'), client_socket)
            else:
                # 如果接收不到数据，说明客户端断开连接
                index = clients.index(client_socket)
                clients.remove(client_socket)
                client_socket.close()
                nickname = nicknames[index]
                nicknames.remove(nickname)
                broadcast(f'{nickname} 离开了聊天室'.encode('utf-8'), client_socket)
                break
        except:
            continue


while True:
    # 等待客户端连接
    client_socket, client_address = server_socket.accept()
    print(f'与客户端 {client_address} 建立连接')

    # 要求客户端发送昵称
    client_socket.send('请输入你的昵称: '.encode('utf-8'))
    nickname = client_socket.recv(1024).decode('utf-8')
    nicknames.append(nickname)
    clients.append(client_socket)

    # 向所有客户端广播新用户加入的消息
    broadcast(f'{nickname} 加入了聊天室'.encode('utf-8'), client_socket)

    # 创建新线程处理该客户端连接
    client_thread = threading.Thread(target=handle_client, args=(client_socket,))
    client_thread.start()